/*
 * ==============================================================================
 *  Name        : WebClientEngine.h
 *  Part of     : WebClient
 *  Interface   : 
 *  Description : 
 *  Version     : 
 *
 *  Copyright (c) 2005-2006 Nokia Corporation.
 *  This material, including documentation and any related 
 *  computer programs, is protected by copyright controlled by 
 *  Nokia Corporation.
 * ==============================================================================
 */

#ifndef WEBCLIENTENGINE_H
#define WEBCLIENTENGINE_H

//#define 	_NOT_USER_SELECT_IAP_
//#define   _ReplaceWapGateway_

// INCLUDES
#include <coecntrl.h>
#include <http.h>
#include <http\mhttpauthenticationcallback.h>
#include <http\mhttptransactioncallback.h>
#include <http\mhttpdatasupplier.h>
#include <ES_SOCK.H>
#include <CommDbConnPref.h>
#include <S32FILE.H>
#include <f32file.h>

// Size of buffers used in WebClient
#define KMaxUriNameLength       128
#define KPrefixedUriNameLength  135
#define KMaxUserNameLength      128
#define KMaxPasswordLength      128
#define KReceiverBufSize		4096  //4k
//http����״̬����
const TInt KHttpInited = 0x1;
const TInt KHttpConnecting = 0x100; //256
const TInt KHttpTransactionCancel = 0x101;
const TInt KHttpResponseCode = 0x102;
const TInt KHttpBodyPartReceived = 0x103;
const TInt KHttpBodyReceived = 0x104; //260
const TInt KHttpTransactionComplete = 0x105;
const TInt KHttpTransactionSucceed = 0x106;
const TInt KHttpTransactionFailed = 0x107;
const TInt KHttpTransactionError = 0x108;
const TInt KHttpUnrecognisedEvent = 0x109;
const TInt KHttpMHFRunError = 0x10A;
const TInt KHttpServerError = 0x10B;
const TInt KHttpHeaderContentLength = 0x10C; //268

// CONSTANTS
const TInt KMaxHeaderNameLength = 32;
const TInt KMaxHeaderValueLength = 128;
const TInt KMaxAuthTypeLength = 128;
const TInt KMaxDateTimeStringLength = 40;
const TInt KMaxStatusTextLength = 32;
// Used user agent for requests
_LIT8( KUserAgent, "Nokia7610");//"MobileExplorer/3.00" );
// This client accepts all content types.
// (change to e.g. "text/plain" for plain text only)
_LIT8(KAccept, "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1, text/vnd.wap.wml, image/vnd.wap.wbmp; level=0");
_LIT8(KAcceptCharset, "iso-8859-1, utf-8, utf-16, *;q=0.1");
_LIT8(KAcceptLanguage," zh-CN,zh;q=0.9,en;q=0.8");
_LIT8(KKeepAlive, "keep-alive");
// Format for output of data/time values
_LIT( KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3" );
// Some texts for header output
_LIT8( KColon, ":" );
_LIT8( Krealm, "Realm" );
//wap���
_LIT8(KWapGetwayIp, "10.0.0.172:80");

// FORWARD DECLARATIONS

// CLASS DECLARATION

/**
 * MWebClientObserver
 * CWebClientEngine passes events and responses body data with this interface. 
 * An instance of this class must be provided for construction of CWebClientEngine.
 */
class MWebClientObserver
{
	
public:
	/**
	 * WebClientEvent()
	 * Called when event occurs in CWebClientEngine.
	 * @param aEventDescription: A event in textual format, e.g.
	 *                           "Transaction Successful"
	 */
	virtual void WebClientEvent (const TInt aEvent, TInt aSessionId,/*const TDesC& aEventDescription,*/
	TInt aCode = 0) = 0;

	/**
	 * WebClientHeaderReceived()
	 * Called when HTTP header is received.
	 * @param aHeaderData: Header field name and value
	 */
	virtual void WebClientHeaderReceived (const TDesC8& aHeaderFiled, const TDesC8& aHeaderVal, TInt aSessionId ) = 0;

	/**
	 * 接收完数据一次传递
	 * WebClientBodyReceivedComplete()
	 * Called when a part of the HTTP body is received.
	 * @param aBodyData:  Part of the body data received. (e.g. part of
	 *                    the received HTML page)
	 *               
	 */
	virtual void WebClientBodyReceivedComplete (const TDesC8& aBodyData, TInt aSessionId ) = 0;

	 /**
	  * 分段传递接收数据
	  * ClientBodyReceived()
	 * Called when a part of the HTTP body is received.
	 * @param aBodyData:  Part of the body data received. (e.g. part of
	 *                    the received HTML page)
	 */
	virtual void
			ClientBodyReceived (const TDesC8& aBodyData, TBool aIsLast ) = 0;
};

/**
 * CWebClientEngine
 * Provides simple interface to HTTP Client API.
 */
class CWebClientEngine : public CBase,
		public MHTTPTransactionCallback,
		public MHTTPAuthenticationCallback,
		public MHTTPDataSupplier
{
public:
	
	/**
	 * NewL()
	 * Create a CWebClientEngine object.
	 * @param  iObserver: 
	 * @return A pointer to the created instance of CWebClientEngine
	 */
	static CWebClientEngine* NewL (MWebClientObserver* aObserver );

	/**
	 * NewLC()
	 * Create a CWebClientEngine object.
	 * @param  iObserver:
	 * @return A pointer to the created instance of CWebClientEngine
	 */
	static CWebClientEngine* NewLC (MWebClientObserver* aObserver );
	
	/**
	 * 切换监听接口 
	 */
	inline void SetObserver(MWebClientObserver* aObserver)
	{
		iObserver = aObserver;
	};
	
	/**
	 * ~CWebClientEngine()
	 * Destroy the object
	 */
	~CWebClientEngine ();

	/**
	 * IssueHTTPGetL()
	 * Starts a new HTTP GET transaction.
	 * @param aUri: URI to get. (e.g. http://host.org")
	 */
	void IssueHTTPGetL (const TDesC8& aUri, TInt aSessionId,
			TBool aReplaceHost = ETrue , TBool aBufferAll = ETrue);

	/**
	 * IssueHTTPPostL()
	 * Starts a new Http post transaction.
	 * @param aUri : uri 
	 * aContentType: Content type of the body, e.g. "text/plain"
	 * &param aBodyData : data to transaction.
	 */
	void IssueHTTPPostL (const TDesC8& aUri, const TDesC8& aBodyData, 
			const TDesC8& aCookie, TInt aSessionId, TBool aBufferAll = ETrue);

	/**
	 * IssueHTTPPostL()
	 * Starts a new Http post transaction.
	 * @param aUri : uri 
	 * &param aBodyData : data to transaction.
	 */
	void IssueHTTPPostL (const TDesC8& aUri, const TDesC8& aBodyData, 
			TInt aSessionId, TBool aBufferAll = ETrue);

	/**
	 * CancelTransactionL()
	 * Closes currently running transaction and frees resources related to it.
	 */
	void CancelTransactionL ();

	/**
	 * IsRunning()
	 * Checks if the transaction is running.
	 * @return ETrue, if transaction is currently running.
	 */
	inline TBool IsRunning ()
	{
		return iRunning;
	};

	inline TInt GetQuerySessionId()
	{
		return iQuerySessionId;
	};

private:
	//��ȡiap����
	void ReadIapIDL (RFileReadStream& aStream, TUint32& aIapID );
	void WriteIapIDL (RFileWriteStream& aStream, TUint32& aIapID );

private:
	/**
	 * ConstructL()
	 * Perform the second phase construction of a CWebClientEngine object.
	 */
	void ConstructL ();

	/**
	 * CWebClientEngine()
	 * Perform the first phase of two phase construction.
	 * @param iObserver: 
	 */
	CWebClientEngine (MWebClientObserver* aObserver );

	/**
	 * SetHeaderL()
	 * Sets header value of an HTTP request.
	 * @param aHeaders:  Headers of the HTTP request
	 * @param aHdrField: Enumerated HTTP header field, e.g. HTTP::EUserAgent
	 * @param aHdrValue: New value for header field
	 */
	void SetHeaderL (RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue );

	/**
	 * AddHeaderL()
	 */
	void AddHeaderL (RHTTPHeaders aHeaders, const TDesC8& aHeaderField, const TDesC8& aHeaderValue );

	/**
	 * DumpRespHeadersL()
	 * Called when HTTP header is received.
	 * Displays HTTP header field names and values
	 * @param aTransaction: The transaction that is processed.
	 */
	void DumpRespHeadersL (RHTTPTransaction& aTransantion );

	/**
	 * ��ȡ������ݳ���
	 */
	void DumpRespContentLength (RHTTPTransaction& aTransantion );

	/**
	 * HandleRunErrorL()
	 * Called from MHFRunError() when *leave* occurs in handling of transaction event. 
	 * @param aError:       The leave code that occured.
	 */
	void HandleRunErrorL (TInt aError );

	/*
	 * From MHTTPDataSupplier (needed for HTTP POST)
	 */
private:
	/*
	 * ReleaseData()
	 *  
	 * Called by framework to allow data supplier to release resources
	 * related to previous data part.
	 */
	void ReleaseData ();

	/*
	 * GetNextDataPart()
	 *  
	 * Called when next data part is needed. 
	 *
	 * Params: 
	 *		aDataPart: Must be set to point to the next data part.
	 */
	TBool GetNextDataPart (TPtrC8& aDataPart );

	/*
	 * Reset()
	 *  
	 * Called by framework to reset the data supplier to its initial state.
	 */
	TInt Reset ();

	/*
	 * OverallDataSize()
	 *  
	 * Called by framework when it needs to know the size of the 
	 * body data.
	 *
	 */
	TInt OverallDataSize ();

	/**
	 * �滻url, ����post�����Ĵ�������
	 */
	void
			ReplaceUriL (const TDesC8& aRowUri, const TDesC8& aNewIP, TDes8& aNewUri, TDes8& aRowIP );

	/**
	 * From MHTTPSessionEventCallback
	 */
private:
	/**
	 * MHFRunL()
	 * Called by framework to notify about transaction events.
	 * @param aTransaction: Transaction, where the event occured.
	 * @param aEvent:       Occured event.
	 */
	void MHFRunL (RHTTPTransaction aTransaction, const THTTPEvent& aEvent );

	/**
	 * MHFRunError()
	 * Called by framework when *leave* occurs in handling of transaction event. 
	 * @param aError:       The leave code that occured.
	 * @param aTransaction: The transaction that was being processed when leave occured.
	 * @param aEvent:       The event that was being processed when leave occured.
	 * @return KErrNone,    if the error was handled. Otherwise the value of aError, or
	 *                      some other error value. Returning error value causes causes 
	 *                      HTTP-CORE 6 panic.
	 */
	TInt
			MHFRunError (TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent );

	/**
	 * From MHTTPAuthenticationCallback (needed for HTTP authentication)
	 */
private:
	/**
	 * GetCredentialsL()
	 * Called by framework when username and password for requested URI is 
	 * needed.
	 * @param aURI: The URI being requested (e.g. "http://host.org")
	 * @param aRealm: The realm being requested (e.g. "user@host.org")
	 * @param aAuthenticationType: Authentication type. (e.g. "Basic")
	 * @param aUsername: Given user name.
	 * @param aPassword: Given password.
	 * @return A pointer to the created document
	 */
	TBool
			GetCredentialsL (const TUriC8& aUri, RString aRealm, RStringF aAuthenticationType, RString& aUsername, RString& aPassword );
	void ReadDataL ();
	void InternalizeL (RReadStream& aStream );

private:
	// Data
	RSocketServ iSocketServ;
	RConnection iConnection;
	RHTTPSession iSession;
	RHTTPTransaction iTransaction;
	MWebClientObserver* iObserver; // ��ݴ��ݽӿ�,not owned
	TBool iRunning; // ETrue, if transaction running
	//������ݻ�����
	//一次接收缓存所有数据
	TBool	i_isBufferAll;//为真的话将数据接收先缓存到i_pReceiveBuf, 待接收完所有再发送
	HBufC8* i_pReceiveBuf;
	HBufC8* iPostData; // Data for HTTP POST
	TBool iDataAvailable;
	TBool iUseApnCMWAP;
	TBool iRing;
	TBool iWall;
	TBool iMagazine;
	TBool iNet;
	
	TInt  iQuerySessionId;

};

#endif // WEBCLIENTENGINE_H
